﻿unit DataPacketSplit;
 
interface

uses
  Winapi.Windows, System.Classes, Protocol, PacketProctol, CircularBuffer,
  EventHandler, ZipTools, System.SysUtils, FMX.Dialogs;

type
  //拼包过程通过工厂查找
                
  TIDataPacketSplit = class
  public
    //根据公共包得到返回结果
    function SplitDP_AnalyseGlobalRes(FDIEventHandler: TIEventHandler; FCircularBuffer: TCircularBuffer;
      FMegPointer: Pointer; var FDIGlobalPak_Responsion: TDIGlobalPak_Responsion): FN_HANDLE_STATUS;
    //抛弃数据包(完成后)
    procedure DeleteLogicDataPack(FCircularBuffer: TCircularBuffer; dpLogicLength: Integer);
  public
    //检查包长度(拆包验证包头)
    function SplitDP_CheckDPLength(FCircularBuffer: TCircularBuffer): TDATAPACK_STATE;
    //再次检查包长度(再次检查长度)
    function SplitDP_AgainCheckDPLength(FCircularBuffer: TCircularBuffer; pGlobalPak_Head: PTDIGlobalPak_Head): TDATAPACK_STATE;
    //服务器检查逻辑包长度
    function SplitDP_ServerCheckLogicBusLen(FCircularBuffer: TCircularBuffer; dpLength: Integer): Boolean;
    //客户端检查逻辑包长度
    //检查公共包长度
    function SplitDP_ClientCheckGlobalPak_ResponsionLen(FCircularBuffer: TCircularBuffer): Boolean;
    //客户端检查逻辑包长度
    function SplitDP_ClientCheckLogicBusLen(FCircularBuffer: TCircularBuffer;
      pGlobalPak_Responsion: PTDIGlobalPak_Responsion; m_nLogDPLen: Integer): Boolean;
    //拆包分析包头
    function SplitDP_AnalyseHead(FDIEventHandler: TIEventHandler;
      pGlobalPak_Head: PTDIGlobalPak_Head): TDATAPACK_STATE;
    //拆包分析包体
    function SplitDP_AnalyseBody(FDIEventHandler: TIEventHandler; pGlobalPak_Body: PTDIGlobalPak_Body): TDATAPACK_STATE;
    //拆包消息分发
    function SplitDP_AnalyseCallEvent(FDIEventHandler: TIEventHandler; pGlobalPak_Body: PTDIGlobalPak_Body): FN_HANDLE_STATUS;
    //服务器拆包返回有用数据
    function SplitDP_ServerGetDataPack(FDIEventHandler: TIEventHandler; FCircularBuffer: TCircularBuffer;
      FDestPointer: Pointer; m_nLogDPLen: Integer): FN_HANDLE_STATUS; overload;
    //服务器拆包返回有用数据
    function SplitDP_ServerGetDataPack(FDIEventHandler: TIEventHandler; FCircularBuffer: TCircularBuffer;
      FDestPointer: Pointer; m_nLogDPLen: Integer; FDestPointerEx: Pointer; m_nLogDPLenEx: Integer): FN_HANDLE_STATUS; overload;
    //客户端拆包返回有用数据(消息+结构体)
    function SplitDP_ClientGetDataPack(FDIEventHandler: TIEventHandler;
      FCircularBuffer: TCircularBuffer; FMegPointer: Pointer;
      FDestPointer: Pointer; m_nLogDPLen: Integer): FN_HANDLE_STATUS; overload;
    function SplitDP_ClientGetDataPack(FDIEventHandler: TIEventHandler;
      FCircularBuffer: TCircularBuffer; FMegPointer: Pointer;
      FDestPointer: Pointer; m_nLogDPLen: Integer;
      FDestPointerEx: Pointer; m_nLogDPLenEx: Integer): FN_HANDLE_STATUS; overload;
    function SplitDP_ClientAnalyseGetDataADOStream(FDIEventHandler: TIEventHandler;
      FCircularBuffer: TCircularBuffer; FMegPointer: Pointer;
      FADOStream: TMemoryStream): FN_HANDLE_STATUS;
    function SplitDP_ClientAnalyseGetDataStream(FDIEventHandler: TIEventHandler;
      FCircularBuffer: TCircularBuffer; FMegPointer: Pointer; FMemStream: TMemoryStream;
      m_nLogDPLen: Integer): FN_HANDLE_STATUS;
    //调用拆包
    procedure ProcessSplitDataPack(FDIEventHandler: TIEventHandler; FCircularBuffer: TCircularBuffer );

  public
    constructor Create;
    destructor Destroy; override;
  end;

var
  _DIDataPacketSplit: TIDataPacketSplit;

implementation

uses FileLogger;

constructor TIDataPacketSplit.Create;
begin
  inherited Create;
end;

destructor TIDataPacketSplit.Destroy;
begin
  inherited Destroy;
end;

procedure TIDataPacketSplit.DeleteLogicDataPack(FCircularBuffer: TCircularBuffer; dpLogicLength: Integer);
begin
  //释放整个数据包(偏移指针)
  FCircularBuffer.HeadSafePosInc(DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + dpLogicLength);
end;

function TIDataPacketSplit.SplitDP_CheckDPLength(FCircularBuffer: TCircularBuffer): TDATAPACK_STATE;
begin
  Result := DP_LENGTH_ENOUGH;
  if FCircularBuffer.GetSafeValidCount < (DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN) then
    Result := DP_LENGTH_NOENOUGH;
end;


function TIDataPacketSplit.SplitDP_AgainCheckDPLength(FCircularBuffer: TCircularBuffer;
  pGlobalPak_Head: PTDIGlobalPak_Head): TDATAPACK_STATE;
begin
  Result := DP_LENGTH_ENOUGH;
  if FCircularBuffer.GetSafeValidCount < (DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN) then
    Result := DP_SPLIT_FAIL
  else if FCircularBuffer.GetSafeValidCount < (DL_GLOBALPAK_HEAD_LEN + pGlobalPak_Head^.dPacketLen) then
    Result := DP_LENGTH_NOENOUGH;
end;


function TIDataPacketSplit.SplitDP_ServerCheckLogicBusLen(FCircularBuffer: TCircularBuffer;
                                                            dpLength: Integer ): Boolean;
begin
  Result := True;
  if FCircularBuffer.GetSafeValidCount < (DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + dpLength)then
  begin
    Result := False;
  end;
end;

function TIDataPacketSplit.SplitDP_ClientCheckGlobalPak_ResponsionLen(FCircularBuffer: TCircularBuffer): Boolean;
begin
  Result := True;
  if FCircularBuffer.GetSafeValidCount <
     (DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + DL_GLOBALPAK_RESPONSION_LEN)then
  begin
    Result := False;
  end;
end;

function TIDataPacketSplit.SplitDP_ClientCheckLogicBusLen(FCircularBuffer: TCircularBuffer;
  pGlobalPak_Responsion: PTDIGlobalPak_Responsion; m_nLogDPLen: Integer): Boolean;
begin
  Result := True;
  //当成功返回时, 如果有后续业务包，则检查业务包长度
  if pGlobalPak_Responsion^.bState = 1 then
  begin
    //检查长度(包头+包体+公共应答包+业务包长度)
    if FCircularBuffer.GetSafeValidCount <
       (DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN +
         DL_GLOBALPAK_RESPONSION_LEN + pGlobalPak_Responsion^.dMsgLen + m_nLogDPLen)then
    begin
      Result := False;
    end;
  end;
end;


function TIDataPacketSplit.SplitDP_AnalyseHead(FDIEventHandler: TIEventHandler;
  pGlobalPak_Head: PTDIGlobalPak_Head): TDATAPACK_STATE;
begin
  //(1.检查帧头起始符 拆包步长：1)
  if FDIEventHandler.FSplitStep = 1 then
  begin
    if pGlobalPak_Head^.bPakHead <> 64 then
    begin
      FDIEventHandler.ReSetSplitStep;
      Result := DP_LOGIC_INVALID;
      Exit;
    end;
    FDIEventHandler.SplitStepAddStep;
  end;
  //(2.检查版本号 拆包步长：2)
  if FDIEventHandler.FSplitStep = 2 then
  begin
    if pGlobalPak_Head^.dVersion <> CD_RACKET_VERSION then
    begin
      FDIEventHandler.ReSetSplitStep;
      Result := DP_LOGIC_INVALID;
      Exit;
    end;
    FDIEventHandler.SplitStepAddStep;
  end;
  Result := DP_LOGIC_VALID;
end;


function TIDataPacketSplit.SplitDP_AnalyseBody(FDIEventHandler: TIEventHandler;
  pGlobalPak_Body: PTDIGlobalPak_Body): TDATAPACK_STATE;
begin
  //(1.检查消息级别 拆包步长：3)
  if FDIEventHandler.FSplitStep = 3 then
  begin
    case pGlobalPak_Body^.bPakLEVEL of
      SM_LEVEL_REALTIME:      ;             //实时
      SM_LEVEL_HIGH:          ;             //高
      SM_LEVEL_IMPORTANCE:    ;             //重要
      SM_LEVEL_NORMAL:        ;             //正常
      SM_LEVEL_LOW:           ;             //低
      SM_LEVEL_IGNORE:        ;             //可忽略
      else
        begin
          FDIEventHandler.ReSetSplitStep;
          Result := DP_LOGIC_INVALID;
          Exit;
        end;
    end;
    FDIEventHandler.SplitStepAddStep;
  end;
  //(2.数据包流向 拆包步长：4)
  if FDIEventHandler.FSplitStep = 4 then
  begin
    case pGlobalPak_Body^.bPakDirection of
      MD_SERVER_TO_CLIENT:    ;             //S->C
      MD_CLIENT_TO_SERVER:    ;             //C->S
      MD_SERVER_TO_SERVER:    ;             //S->S
      MD_CLIENT_TO_CLIENT:    ;             //C->C
      MD_SERVER_TO_BROADCAST: ;             //S->B
      MD_CLIENT_TO_BROADCAST: ;             //C->B
      else
        begin
          FDIEventHandler.ReSetSplitStep;
          Result := DP_LOGIC_INVALID;
          Exit;
        end;
    end;
    FDIEventHandler.SplitStepAddStep;
  end;
  //(3.业务类别标识 拆包步长：5)
  if FDIEventHandler.FSplitStep = 5 then
  begin
    case pGlobalPak_Body^.bPakKind of
      BK_NORMAL_SIGN:         ;             //通用类别
      BK_CHAT_SIGN:           ;             //聊天类别
      BK_FTP_SIGN:            ;             //FTP类别
      BK_DB_SIGN:             ;
      BK_MAIL_SIGN:           ;
      BK_MESSAGE_SIGN:        ;
      else
        begin
          FDIEventHandler.ReSetSplitStep;
          Result := DP_LOGIC_INVALID;
          Exit;
        end;
    end;
    FDIEventHandler.SplitStepAddStep;
  end;
  Result := DP_LOGIC_VALID;
end;


function TIDataPacketSplit.SplitDP_AnalyseCallEvent(FDIEventHandler: TIEventHandler;
  pGlobalPak_Body: PTDIGlobalPak_Body): FN_HANDLE_STATUS;
begin
  Result := FN_HANDLE_FAIL;
  //(具体消息分发 拆包步长：6)
  if FDIEventHandler.FSplitStep = 6 then
  begin
    //(事件分发)
    Result := FDIEventHandler.HandleEvent(pGlobalPak_Body^.bPakCmd);
    if Result = FN_HANDLE_NOTEXIST then
    begin
      FDIEventHandler.ReSetSplitStep;
    end;
  end;
end;

function TIDataPacketSplit.SplitDP_ServerGetDataPack(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FDestPointer: Pointer; m_nLogDPLen: Integer): FN_HANDLE_STATUS;
begin
  //检查需要返回的包长度
  if not SplitDP_ServerCheckLogicBusLen(FCircularBuffer, m_nLogDPLen) then
  begin
    Result := FN_HANDLE_SPLIT_DATAPACK;
    Exit;
  end;
  //得到偏移位置
  FCircularBuffer.ReadCirBuffer(FDestPointer, m_nLogDPLen,
    DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN);
  //释放整个数据包(偏移指针)
  DeleteLogicDataPack(FCircularBuffer, m_nLogDPLen);
  //初始步长
  FDIEventHandler.ReSetSplitStep;
  Result := FN_HANDLE_SUCCESS;
end;

function TIDataPacketSplit.SplitDP_ServerGetDataPack(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FDestPointer: Pointer; m_nLogDPLen: Integer;
  FDestPointerEx: Pointer; m_nLogDPLenEx: Integer): FN_HANDLE_STATUS;
begin
  //检查需要返回的包长度
  if not SplitDP_ServerCheckLogicBusLen(FCircularBuffer, m_nLogDPLen + m_nLogDPLenEx ) then
  begin
    Result := FN_HANDLE_SPLIT_DATAPACK;
    Exit;
  end;
  //得到偏移位置
  FCircularBuffer.ReadCirBuffer(FDestPointer, m_nLogDPLen,
    DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN);
  //得到偏移位置
  FCircularBuffer.ReadCirBuffer(FDestPointerEx, m_nLogDPLenEx,
    DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + m_nLogDPLen);
  //释放整个数据包(偏移指针)
  DeleteLogicDataPack(FCircularBuffer, m_nLogDPLen + m_nLogDPLenEx);
  //初始步长
  FDIEventHandler.ReSetSplitStep;
  Result := FN_HANDLE_SUCCESS;
end;

function TIDataPacketSplit.SplitDP_AnalyseGlobalRes(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FMegPointer: Pointer;
  var FDIGlobalPak_Responsion: TDIGlobalPak_Responsion): FN_HANDLE_STATUS;
var
  dMsgLen: Cardinal;
begin
  //检查公共返回包需要长度
  if not SplitDP_ClientCheckGlobalPak_ResponsionLen(FCircularBuffer) then
  begin
    Result := FN_HANDLE_SPLIT_DATAPACK;
    Exit;
  end;
  //取得服务器返回的公共包
  ZeroMemory(@FDIGlobalPak_Responsion, DL_GLOBALPAK_RESPONSION_LEN);
  FCircularBuffer.ReadCirBuffer(@FDIGlobalPak_Responsion, DL_GLOBALPAK_RESPONSION_LEN,
    DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN);
  dMsgLen := FDIGlobalPak_Responsion.dMsgLen;
  //返回上层最大缓冲
  if dMsgLen > 1024 then dMsgLen := 1024;
  //检查返回字符串包需要长度
  if not SplitDP_ClientCheckLogicBusLen(FCircularBuffer, @FDIGlobalPak_Responsion, 0) then
  begin
    Result := FN_HANDLE_SPLIT_DATAPACK;
    Exit;
  end;
  //得到偏移位置(服务器字串)
  if dMsgLen > 0 then
  begin
    FCircularBuffer.ReadCirBuffer(FMegPointer, dMsgLen,
      DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + DL_GLOBALPAK_RESPONSION_LEN);
  end;
  if FDIGlobalPak_Responsion.bState = 1 then
    Result := FN_HANDLE_SUCCESS
  else
    Result := FN_HANDLE_FAIL;
  if Result = FN_HANDLE_FAIL then
  begin
    //释放整个数据包(公共返回+字串)
    DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN + FDIGlobalPak_Responsion.dMsgLen);
    //初始步长
    FDIEventHandler.ReSetSplitStep;
    Result := FN_HANDLE_FAIL;
  end;
end;

function TIDataPacketSplit.SplitDP_ClientGetDataPack(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FMegPointer: Pointer; FDestPointer: Pointer;
  m_nLogDPLen: Integer): FN_HANDLE_STATUS;
var
  FDIGlobalPak_Responsion: TDIGlobalPak_Responsion;
begin
  Result := SplitDP_AnalyseGlobalRes(FDIEventHandler, FCircularBuffer,
    FMegPointer, FDIGlobalPak_Responsion);
  if Result = FN_HANDLE_SUCCESS then
  begin
    if m_nLogDPLen > 0 then
    begin
      //检查需要返回的包长度(应答包(含字符串)之后的逻辑包长度)
      if not SplitDP_ClientCheckLogicBusLen(FCircularBuffer, @FDIGlobalPak_Responsion,
        m_nLogDPLen) then
      begin
        Result := FN_HANDLE_SPLIT_DATAPACK;
        Exit;
      end;
      //得到偏移位置(后续包)
      FCircularBuffer.ReadCirBuffer(FDestPointer, m_nLogDPLen,
        DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN +
        DL_GLOBALPAK_RESPONSION_LEN + FDIGlobalPak_Responsion.dMsgLen);
      //释放整个数据包(公共返回+字串+业务后续包)
      DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN +
        FDIGlobalPak_Responsion.dMsgLen + m_nLogDPLen);
    end
    else
      //释放整个数据包(公共返回+字串)
      DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN +
        FDIGlobalPak_Responsion.dMsgLen);
    //初始步长
    FDIEventHandler.ReSetSplitStep;
    Result := FN_HANDLE_SUCCESS;
  end;
end;

function TIDataPacketSplit.SplitDP_ClientGetDataPack(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FMegPointer: Pointer; FDestPointer: Pointer;
  m_nLogDPLen: Integer; FDestPointerEx: Pointer; m_nLogDPLenEx: Integer): FN_HANDLE_STATUS;
var
  FDIGlobalPak_Responsion: TDIGlobalPak_Responsion;
begin
  Result := SplitDP_AnalyseGlobalRes(FDIEventHandler, FCircularBuffer, FMegPointer,
    FDIGlobalPak_Responsion);
  if Result = FN_HANDLE_SUCCESS then
  begin
    //检查需要返回的包长度(应答包(含字符串)之后的逻辑包长度)
    if not SplitDP_ClientCheckLogicBusLen(FCircularBuffer, @FDIGlobalPak_Responsion,
      m_nLogDPLen + m_nLogDPLenEx ) then
    begin
      Result := FN_HANDLE_SPLIT_DATAPACK;
      Exit;
    end;
    //得到偏移位置(后续包)
    FCircularBuffer.ReadCirBuffer(FDestPointer, m_nLogDPLen, DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN +
      DL_GLOBALPAK_RESPONSION_LEN + FDIGlobalPak_Responsion.dMsgLen);
    //得到偏移位置(后续包2)
    FCircularBuffer.ReadCirBuffer(FDestPointerEx, m_nLogDPLenEx, DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN +
      DL_GLOBALPAK_RESPONSION_LEN + FDIGlobalPak_Responsion.dMsgLen + m_nLogDPLen);
    //释放整个数据包(公共返回+字串+业务后续包)
    DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN + FDIGlobalPak_Responsion.dMsgLen +
      m_nLogDPLen + m_nLogDPLenEx);
    //初始步长
    FDIEventHandler.ReSetSplitStep;
    Result := FN_HANDLE_SUCCESS;
  end;
end;

function TIDataPacketSplit.SplitDP_ClientAnalyseGetDataStream(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FMegPointer: Pointer; FMemStream: TMemoryStream;
  m_nLogDPLen: Integer ): FN_HANDLE_STATUS;
begin
  Result := FN_HANDLE_FAIL;
end;

function TIDataPacketSplit.SplitDP_ClientAnalyseGetDataADOStream(FDIEventHandler: TIEventHandler;
  FCircularBuffer: TCircularBuffer; FMegPointer: Pointer; FADOStream: TMemoryStream): FN_HANDLE_STATUS;
var
  dMsgLen: Cardinal;
  GlobalPak_Responsion: TDIGlobalPak_Responsion;
  Pak_DB_GetDataEx: TDIPak_DB_GetDataEx;
begin
  //检查公共返回包需要长度
  if not SplitDP_ClientCheckGlobalPak_ResponsionLen(FCircularBuffer) then
  begin
    Result := FN_HANDLE_SPLIT_DATAPACK;
    Exit;
  end;
  //拆分公共返回包
  ZeroMemory(@GlobalPak_Responsion, DL_GLOBALPAK_RESPONSION_LEN);
  FCircularBuffer.ReadCirBuffer(@GlobalPak_Responsion, DL_GLOBALPAK_RESPONSION_LEN,
    DL_GLOBALPAK_HEAD_LEN+ DL_GLOBALPAK_BODY_LEN );
  //取得服务器返回的公共包
  dMsgLen := GlobalPak_Responsion.dMsgLen;
  if dMsgLen > 1024 then dMsgLen := 1024;
  //得到偏移位置(服务器字串)
  if dMsgLen > 0 then
  begin
    FCircularBuffer.ReadCirBuffer(FMegPointer, dMsgLen,
      DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + DL_GLOBALPAK_RESPONSION_LEN);
  end;
  //当成功返回
  if GlobalPak_Responsion.bState = 1 then
  begin
    //检查需要返回的包长度(应答包(含字符串)之后的逻辑包FDIPak_CHAT_GetDataEx)
    if not SplitDP_ClientCheckLogicBusLen(FCircularBuffer, @GlobalPak_Responsion,
      DL_PAK_DBGETDATAEX_LEN) then
    begin
      Result := FN_HANDLE_SPLIT_DATAPACK;
      Exit;
    end;
    ZeroMemory(@Pak_DB_GetDataEx, DL_PAK_DBGETDATAEX_LEN);
    FCircularBuffer.ReadCirBuffer(@Pak_DB_GetDataEx, DL_PAK_DBGETDATAEX_LEN,
      DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN + DL_GLOBALPAK_RESPONSION_LEN
      + GlobalPak_Responsion.dMsgLen);
    if Pak_DB_GetDataEx.dDBPakHead <> CD_RACKET_HEAD then
    begin
      Result := FN_HANDLE_SPLIT_DATAPACK;
      Exit;
    end;
    if Pak_DB_GetDataEx.dDBVersion <> CD_RACKET_VERSION then
    begin
      Result := FN_HANDLE_SPLIT_DATAPACK;
      Exit;
    end;
    //检查需要返回的ADO流包长度
    if not SplitDP_ClientCheckLogicBusLen(FCircularBuffer, @GlobalPak_Responsion,
      DL_PAK_DBGETDATAEX_LEN+ Pak_DB_GetDataEx.dDBPacketLen) then
    begin
      Result := FN_HANDLE_SPLIT_DATAPACK;
      Exit;
    end;
    //定位到ADO流数据
    FADOStream.Position := 0;
    FADOStream.SetSize(Pak_DB_GetDataEx.dDBPacketLen);
    //得到后续ADODS包
    FCircularBuffer.ReadCirBuffer(FADOStream.Memory,
      Pak_DB_GetDataEx.dDBPacketLen, DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN+
      DL_GLOBALPAK_RESPONSION_LEN + GlobalPak_Responsion.dMsgLen + DL_PAK_DBGETDATAEX_LEN);
    if Pak_DB_GetDataEx.dDBCompress = 1 then
    begin
      TZipTools.unCompressStreamEX(FADOStream);
    end;
    //释放整个数据包(公共返回+字串+业务后续包)
    DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN + GlobalPak_Responsion.dMsgLen +
      DL_PAK_DBGETDATAEX_LEN + Pak_DB_GetDataEx.dDBPacketLen);
    Result := FN_HANDLE_SUCCESS;
  end
  else
  begin
    //释放整个数据包(公共返回+字串)
    DeleteLogicDataPack(FCircularBuffer, DL_GLOBALPAK_RESPONSION_LEN + GlobalPak_Responsion.dMsgLen);
    //初始步长
    FDIEventHandler.ReSetSplitStep;
    Result := FN_HANDLE_FAIL;
  end;
end;

procedure TIDataPacketSplit.ProcessSplitDataPack(FDIEventHandler: TIEventHandler; FCircularBuffer: TCircularBuffer);
var
  FDIGlobalPak_Head: TDIGlobalPak_Head;
  FDIGlobalPak_Body: TDIGlobalPak_Body;
LABEL SplitDataPack;
begin
  //开始拆包
  SplitDataPack:
  //无效长度包(需要继续拆包)
  if SplitDP_CheckDPLength(FCircularBuffer) = DP_LENGTH_NOENOUGH then Exit;
  //拆分包头
  ZeroMemory(@FDIGlobalPak_Head, DL_GLOBALPAK_HEAD_LEN);
  FCircularBuffer.ReadCirBuffer(@FDIGlobalPak_Head, DL_GLOBALPAK_HEAD_LEN, 0);
  case SplitDP_AnalyseHead(FDIEventHandler, @FDIGlobalPak_Head) of
    DP_LENGTH_NOENOUGH: Exit;                   //收到的缓冲区长度小于逻辑包长度(需要继续拆包)
    DP_LOGIC_INVALID:
      begin
        //错误数据丢弃包头DL_GLOBALPAK_HEAD_LEN 逻辑无效包(需要丢弃包)
        FCircularBuffer.HeadSafePosInc(DL_GLOBALPAK_HEAD_LEN);
        GOTO SplitDataPack;     
      end;
  end;
  //拆分包体
  ZeroMemory(@FDIGlobalPak_Body, DL_GLOBALPAK_BODY_LEN);
  FCircularBuffer.ReadCirBuffer(@FDIGlobalPak_Body, DL_GLOBALPAK_BODY_LEN, DL_GLOBALPAK_HEAD_LEN);
  //逻辑有效包(下一步拆包)
  if SplitDP_AnalyseBody(FDIEventHandler, @FDIGlobalPak_Body) = DP_LOGIC_INVALID then
  begin
    //错误数据丢弃包头DL_GLOBALPAK_HEAD_LEN+DL_GLOBALPAK_BODY_LEN
    FCircularBuffer.HeadSafePosInc(DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN);
    GOTO SplitDataPack;
  end;
  //再次检查包长度
  if SplitDP_AgainCheckDPLength(FCircularBuffer, @FDIGlobalPak_Head) = DP_LENGTH_NOENOUGH then Exit;
  //处理业务方法调用
  case SplitDP_AnalyseCallEvent(FDIEventHandler, @FDIGlobalPak_Body) of
  FN_HANDLE_NOTEXIST:                         //方法不存在(数据包有误)
    FCircularBuffer.HeadSafePosInc(DL_GLOBALPAK_HEAD_LEN + DL_GLOBALPAK_BODY_LEN);
  FN_HANDLE_SPLIT_DATAPACK: Exit;             //数据包长度不够(下次继续处理)
  FN_HANDLE_SUCCESS,                          //返回成功
  FN_HANDLE_FAIL:                             //返回失败
    GOTO SplitDataPack;
  end;
  GOTO SplitDataPack;                           //下一次拆包(直到长度无效)
end;

initialization
  _DIDataPacketSplit := TIDataPacketSplit.Create;

finalization
  _DIDataPacketSplit.Free;
  
end.
